package org.broadband_forum.obbaa.netconf.mn.fwk.server.model.datastore;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.broadband_forum.obbaa.netconf.persistence.EntityDataStoreManager;
import org.broadband_forum.obbaa.netconf.stack.logging.AdvancedLogger;
import org.broadband_forum.obbaa.netconf.stack.logging.AdvancedLoggerUtil;
import org.broadband_forum.obbaa.netconf.stack.logging.LogAppNames;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;

public class ModelNodeDSMRegistryImpl implements ModelNodeDSMRegistry {

	private Map<SchemaPath, ModelNodeDataStoreManager> m_registry = new ConcurrentHashMap<>();
	private final static ModelNodeDSMRegistry INSTANCE = new ModelNodeDSMRegistryImpl();
	private ConcurrentHashMap<String, List<SchemaPath>> m_componentMap = new ConcurrentHashMap<>();
	private static final AdvancedLogger LOGGER = AdvancedLoggerUtil.getGlobalDebugLogger(ModelNodeDSMRegistryImpl.class, LogAppNames.NETCONF_STACK);
	private final Map<Class, EntityDataStoreManager> m_entityDSMs = new ConcurrentHashMap<>();

    public ModelNodeDSMRegistryImpl() {}
	
	public static ModelNodeDSMRegistry getInstance() {
		return INSTANCE;
	}

	public void undeploy(String componentId){
		List<SchemaPath> schemaPathList = m_componentMap.get(componentId);
		if(schemaPathList != null) {
			m_registry.keySet().removeAll(schemaPathList);
		}
        LOGGER.debug("un-registered {}" , componentId);
		m_componentMap.remove(componentId);
	}

	@Override
	public Set<ModelNodeDataStoreManager> getAllDSMs() {
		return new HashSet<>(m_registry.values());
	}

	@Override
	public void register(String componentId, SchemaPath schemaPath, ModelNodeDataStoreManager modelNodeDataStoreManager) {
		m_registry.put(schemaPath, modelNodeDataStoreManager);
		addSchemaPathList(componentId, schemaPath);
		LOGGER.debug("Registered a ModelNodeDataStoreManager with schemaPath: {}", schemaPath.toString());
	}

	private void addSchemaPathList(String componentId, SchemaPath schemaPath) {
		List<SchemaPath> schemaPathList = m_componentMap.get(componentId);
		if(schemaPathList == null){
			schemaPathList = new ArrayList<>();
			m_componentMap.putIfAbsent(componentId, schemaPathList);
			schemaPathList = m_componentMap.get(componentId);
		}
		schemaPathList.add(schemaPath);
	}

	@Override
	public ModelNodeDataStoreManager lookupDSM(SchemaPath schemaPath) {
		if(schemaPath != null){
			ModelNodeDataStoreManager modelNodeDataStoreManager = m_registry.get(schemaPath);
			return modelNodeDataStoreManager;
		}
		return null;
	}

    @Override
    public EntityDataStoreManager getEntityDSM(Class klass) {
        return m_entityDSMs.get(klass);
    }

    @Override
    public void addEntityDSM(Class klass, EntityDataStoreManager entityDSM) {
        m_entityDSMs.put(klass, entityDSM);
    }
}
